/*
 * revaDAO.java
 *
 * Created on March 17, 2007, 2:14 PM
 */

package edu.byu.isys413.mystuff;

import java.util.*;
import java.sql.*;

/**
 *
 * @author Sam Griffiths
 */
public abstract class revaDAO {
    
    //initializes variables
    private static revaDAO instance;
    private String revid;
    private static Cache cache;
    
    /** Creates a new instance of revaDAO */
    public revaDAO() {
    cache = Cache.getInstance();
    }
    
    /////////////////////////////////
    ///   CREATE
    
     
    
    /** 
     *Abstract method to require every extending class to have a create method..
     * 
     * @return revBO revBO;
     */ 
    public abstract revaBO create() throws Exception;
//        revid = Guid.generate();
//        revBO rev = new revBO(revid);
//        cache.put(revid, rev);
//        return rev;
    
    /////////////////////////////////////
    ///   READ
    
    /** 
     * Public read statement that retrieves an exising object from the database
     * in the form of an object. Trtrieves a connection and passes the connection 
     * to a second read method 
     * 
     * @param String id
     * @return RevenueSource revBO
     */
    public synchronized void read(String revid) throws DataException{
        Connection conn = null;
        try {
            //get connection, call read with connection
            conn = ConnectionPool.getInstance().get();
            read(conn, revid);
            
            // release the connection
            conn.commit();
            ConnectionPool.getInstance().release(conn);
            
        }catch (ConnectionPoolException e){
            throw new DataException("Could not get a connection to the database.");
            
        }catch (SQLException e) {
            // rollback
            try {
                conn.rollback();
                ConnectionPool.getInstance().release(conn);
            }catch (SQLException e2) {
                throw new DataException("Big error: could not even release the connection", e2);
            }catch (ConnectionPoolException e3){
            }
            
            throw new DataException("Could not retrieve records", e);
        }
    }
    
     /** 
     *  This is a  method that is called by the public read (above) or
     *  by another DAO. We already have a connection to the database.
     *  The controller will never call this one method directly, because
     *  it should not know about SQL exceptions or connection objects.
     * 
     *  @param Connection conn, String id
     *         
     *  @return ReveneSourceBO revBO
     */
   
    public synchronized void read(Connection conn, String id){
       revaBO rev = (revaBO)cache.get(revid);
        try{
        Statement st = conn.createStatement();
            ResultSet rs = st.executeQuery("SELECT * FROM REV_TABLE WHERE REVID='"+id+"'");
            while(rs.next()){
                rev.setPrice(Double.valueOf(rs.getString("PRICE").trim()).doubleValue());
                rev.setType(rs.getString("TYPE"));
                rev.setAlreadyInDatabase(true);
            }
       }catch(Exception e){}
    }
    
//////////////////////////////////
    ///   UPDATE
    
    /** 
     * This is the public save method. This method is called when the user would like
     * to save an object to the DB. This method checks to see if an object is dirty, retrieves 
     *connection, and calls a second save method 
     *
     * @param RevenueSourceBO revBO
     *
     */
     
    
    public synchronized boolean save(String revid) throws DataException {
       System.out.println("Save entrance accessed");
        Connection conn = null;
        try {
            
            conn = ConnectionPool.getInstance().get();
            revaBO rev = (revaBO)cache.get(revid);
            if(rev.isDirty())
                save(conn,revid);
            
            ///////////////////////////////////////////
            // call read with a connection (the other read method in this class)
            
            // release the connection
            conn.commit();
            ConnectionPool.getInstance().release(conn);
            
        }catch (ConnectionPoolException e){
            throw new DataException("Could not get a connection to the database.");
            
        }catch (SQLException e) {
            // rollback
            try {
                conn.rollback();
                ConnectionPool.getInstance().release(conn);
            }catch (SQLException e2) {
                throw new DataException("Big error: could not even release the connection", e2);
            }catch (ConnectionPoolException e3){
            }
            
            throw new DataException("Could not retrieve records", e);
        }
        
        return true;
        }
    
    /**
     *  This is a  method that is called by the public save (above) or
     *  by another DAO. We already have a connection to the database.
     *  The controller will never call this one method directly, because
     *  it should not know about SQL exceptions or connection objects.
     *
     */
    
    
    //checks to see if already in database, result = insert or update of BO
    public synchronized void save(Connection conn, String revid){
        System.out.println("Second Save Accessed");
        try{
            revaBO rev = (revaBO)cache.get(revid);
            Statement st = conn.createStatement();
           
            System.out.println("First Query Skipped");
            if(false == rev.isAlreadyInDatabase()){
                
                String queryString = "INSERT INTO REV_TABLE VALUES (?,?,?)";
                PreparedStatement pstmt = conn.prepareStatement(queryString);
               
                //String aString = Double.toString(aDouble);
                pstmt.setString(1,rev.getRevenueId());
                pstmt.setString(2,Double.toString(rev.getPrice()));
                pstmt.setString(3,rev.getType());
                pstmt.execute();
                pstmt.close();
            } else{
            
                String queryString = "UPDATE REV_TABLE SET PRICE = ?, TYPE = ? WHERE REVID = ? ";
                PreparedStatement pstmt = conn.prepareStatement(queryString);
                pstmt.setString(1,Double.toString(rev.getPrice()));
                pstmt.setString(2,rev.getType());
                pstmt.setString(3,rev.getRevenueId());
                pstmt.execute();
                pstmt.close();
                
            }
        }catch(Exception e){}
    }
    
    /////////////delete////////////////////////
    /*
        We don't need a delete for revenue source, especially since it's just a little black box
     */
    
}
